package com.woniu.apartment.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ruoyi.common.constant.ShaoxiaConstants;
import com.ruoyi.common.utils.ShaoxUtil;
import com.woniu.apartment.util.FileUntil;
import com.woniu.apartment.domain.ApartmentMain;
import com.woniu.apartment.mapper.ApartmentMainMapper;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.woniu.apartment.mapper.CommentsMapper;
import com.woniu.apartment.domain.Comments;
import com.woniu.apartment.service.ICommentsService;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 评论Service业务层处理
 *
 * @author yy
 * @date 2023-04-03
 */
@Service
public class CommentsServiceImpl implements ICommentsService {
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private CommentsMapper commentsMapper;
    @Autowired
    private ApartmentMainMapper apartmentMainMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 查询评论
     *
     * @param id 评论主键
     * @return 评论
     */
    @Override
    public Comments selectCommentsById(Long id) {
        return commentsMapper.selectCommentsById(id);
    }

    /**
     * 查询评论列表
     *
     * @param comments 评论
     * @return 评论
     */
    @Override
    public List<Comments> selectCommentsList(Comments comments) {
        return commentsMapper.selectCommentsList(comments);
    }

    /**
     * 新增评论
     *
     * @param comments 评论
     * @return 结果
     */
    @Override
    public int insertComments(Comments comments) {
        return commentsMapper.insertComments(comments);
    }

    /**
     * 修改评论
     *
     * @param comments 评论
     * @return 结果
     */
    @Override
    public int updateComments(Comments comments) {
        return commentsMapper.updateComments(comments);
    }

    /**
     * 批量删除评论
     *
     * @param ids 需要删除的评论主键
     * @return 结果
     */
    @Override
    public int deleteCommentsByIds(Long[] ids) {
        return commentsMapper.deleteCommentsByIds(ids);
    }

    /**
     * 删除评论信息
     *
     * @param id 评论主键
     * @return 结果
     */
    @Override
    public int deleteCommentsById(Long id) {
        return commentsMapper.deleteCommentsById(id);
    }

    @Override
    public List<Comments> selectCommentsByApartId(Long apartmentId) {
        List<Comments> comments;
        //redis中拿到评论 Map以用户ID为key Comments为值
        Map entries = redisTemplate.opsForHash().entries(ShaoxiaConstants.APARTMENT_COMMENT + apartmentId);

        if (!entries.isEmpty()){
            List<Comments> commentsList = new ArrayList<>();
            entries.forEach((t,u)->{
                commentsList.add((Comments) u);
            });
            return commentsList;
        }
        //加锁
        RLock lock = redissonClient.getLock("redis_comments");
        try {
            //在查一次
           entries = redisTemplate.opsForHash().entries(ShaoxiaConstants.APARTMENT_COMMENT + apartmentId);
            if (!entries.isEmpty()){
                List<Comments> commentsList = new ArrayList<>();
                entries.forEach((t,u)->{
                    commentsList.add((Comments) u);
                });
                return commentsList;
            }
             comments = commentsMapper.selectCommentsByApartId(apartmentId);
            Map<String,Comments> hashMap = new HashMap();
            for (Comments comment : comments) {
                hashMap.put(comment.getCustomerId()+"", comment);
            }
            redisTemplate.opsForHash().putAll(ShaoxiaConstants.APARTMENT_COMMENT + apartmentId,hashMap);

        }finally {
           if (lock.isLocked() && lock.isHeldByCurrentThread()){
                lock.unlock();//解锁
          }
        }
        return comments;


    }

    @Override
    public void change(Comments comments, Long apartmentId) {
        //拿到用户信息 并拿到用户
        String name = ShaoxUtil.getUserDtoName();
        Long userId = ShaoxUtil.getUserDtoId();
        //根据用户Id以及公寓id查用户是否评价过
        Comments comments1 = listByApartIdAndUserId(apartmentId, userId);
        comments.setComments(FileUntil.filterSensitivityWord(comments.getComments(),'*'));
        comments.setCustomerId(userId);
        comments.setCustomerName(name);
        comments.setApartId(apartmentId);
        comments.setScore((comments.getFacilityScore()+comments.getTrafficScore()+comments.getServiceScore()+comments.getSecurityScore()+comments.getCostPerScore())/5);
        if (comments1 != null){
            //评价过 直接修改 重新算公寓的总评分
            commentsMapper.updateComments(comments);
        }else{
            commentsMapper.insertComments(comments);
            //公寓评级数目+1
            apartmentMainMapper.updateSocerById(apartmentId);
        }
        Map entries = redisTemplate.opsForHash().entries(ShaoxiaConstants.APARTMENT_COMMENT + apartmentId);
        entries.put(userId+"",comments);
        redisTemplate.opsForHash().putAll(ShaoxiaConstants.APARTMENT_COMMENT + apartmentId,entries);
        //重新生成公寓评分
        restartScore(apartmentId, entries);


    }

    private void restartScore(Long apartmentId, Map entries) {
        Long fs=0L;
        Long ts=0L;
        Long ss=0L;
        Long sss=0L;
        Long cs=0L;
        Long s=0L;
        List<Comments> commentsList=new ArrayList<>();
        entries.forEach((t, u)->{
            commentsList.add((Comments) u);
        });
        for (Comments comments2 : commentsList) {
            fs+=comments2.getFacilityScore();
            ts+=comments2.getTrafficScore();
            ss+=comments2.getSecurityScore();
            sss+=comments2.getServiceScore();
            cs+=comments2.getCostPerScore();
        }
        s=(fs+ts+ss+sss+cs)/5;
        ApartmentMain apartmentMain = apartmentMainMapper.selectApartmentMainById(apartmentId);
        apartmentMain.setFacilityScore(fs/apartmentMain.getComments());
        apartmentMain.setTrafficScore(ts/apartmentMain.getComments());
        apartmentMain.setSecurityScore(ss/apartmentMain.getComments());
        apartmentMain.setServiceScore(sss/apartmentMain.getComments());
        apartmentMain.setCostPerScore(cs/apartmentMain.getComments());
        apartmentMain.setScore(s/apartmentMain.getComments());
        apartmentMainMapper.updateApartmentMain(apartmentMain);
    }

    @Override
    public Comments listByApartIdAndUserId(Long apartmentId, Long userId) {

            return commentsMapper.listByApartIdAndUserId(apartmentId,userId);

    }


}

